/*
 * Copyright 2025 arisgo@163.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arisgo.cloud.attendance.clazz.core.arrange;

import com.arisgo.cloud.attendance.clazz.core.ArrangeContext;
import com.arisgo.cloud.attendance.clazz.entity.Group;
import com.arisgo.cloud.attendance.clazz.mapper.ClassDetailMapper;
import com.arisgo.cloud.attendance.clazz.mapper.ClassInfoMapper;
import com.arisgo.cloud.attendance.clazz.mapper.ClassSegmentMapper;
import com.arisgo.cloud.attendance.clazz.mapper.ClassShiftMapper;
import com.arisgo.cloud.attendance.clazz.mapper.GroupMapper;
import com.arisgo.cloud.attendance.clazz.mapper.GroupStaffMapper;
import com.arisgo.cloud.attendance.clazz.mapper.HolidayMapper;
import com.arisgo.cloud.attendance.clazz.mapper.StaffClassMapper;
import com.arisgo.cloud.attendance.clazz.mapper.StaffMapper;
import com.arisgo.cloud.attendance.clazz.mapper.WorkSystemDetailMapper;
import com.arisgo.cloud.attendance.clazz.mapper.WorkdayMapper;
import com.arisgo.cloud.common.utils.AssertUtil;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author xu keqi
 * @since 2025-03-29
 */
@Component
public class AutoArrange extends StandardArrange {

    public static final String KEY = "auto";
    // TODO 2025-03-29 此处有问题
    // 线程池跟随bean初始化，跑自动排班的线程永远是30个，如果某个租户有30个以上班组，则会将此线程池占用完，导致其他租户用不了
    // 优化：每次点击，如果班组多于10个，则创建线程数为5的线程池供此次调用
    // 问题：每点一次方法，创建一个线程池，也会很耗资源
    private final ExecutorService executor = Executors.newFixedThreadPool(30);

    public AutoArrange(MatchStore matchStore, ArrangeStore arrangeStore, StaffMapper staffMapper, WorkSystemDetailMapper workSystemDetailMapper,
                       HolidayMapper holidayMapper, ClassInfoMapper classInfoMapper, ClassShiftMapper classShiftMapper, GroupStaffMapper groupStaffMapper,
                       StaffClassMapper staffClassMapper, WorkdayMapper workdayMapper, GroupMapper groupMapper, ClassSegmentMapper classSegmentMapper, ClassDetailMapper classDetailMapper) {
        super(matchStore, arrangeStore, staffMapper, holidayMapper, workSystemDetailMapper, classInfoMapper, classShiftMapper, staffClassMapper, workdayMapper, groupStaffMapper, groupMapper, classSegmentMapper, classDetailMapper);
    }

    @Override
    public void validate(ArrangeContext context) {
        AssertUtil.notNull(context, "参数为空！");
        AssertUtil.notEmpty(groupMapper.findGroupByTenantId(context.getTenantId()), "班组为空！");
    }

    @Override
    public boolean arrange(ArrangeContext context) {
        long start = System.currentTimeMillis();
        logger.info("自动排班 => 开始: {}", start);
        // 获取班组
        List<Group> groups = groupMapper.findGroupByTenantId(context.getTenantId());
        AssertUtil.notEmpty(groups, "班组为空！");
        for (Group group : groups) {
            logger.info("自动排班 => 排班班组信息: id: {}, name: {}", group.getId(), group.getName());
            context.setGroupId(group.getId());
            CompletableFuture.runAsync(() -> super.arrange(context.clone()), executor);
        }
        long end = System.currentTimeMillis();
        logger.info("自动排班 => 完成时间: {}，耗时: {}", end, end - start);
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        arrangeStore.add(KEY, this);
    }
}
